package com.oro.domain;

import static javax.persistence.CascadeType.ALL;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Transient;

import org.hibernate.validator.NotNull;

/**
 * Entity implementation class for Entity: Contatto
 * 
 */
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Contatto implements Serializable {

	@Transient
	public static final String DR = "Dr.";

	@Transient
	public static final String LADY = "Lady";

	@Transient
	public static final String MISS = "Miss.";
	@Transient
	public static final String MR = "Mr.";
	@Transient
	public static final String MRS = "Mrs.";
	private static final long serialVersionUID = 1L;
	@Transient
	public static final String SIR = "Sir";
	@Transient
	private static final List<String> titles = new ArrayList<String>() {
		private static final long serialVersionUID = 1L;
		{
			add(MR);
			add(MISS);
			add(MRS);
			add(DR);
			add(SIR);
			add(LADY);
		}
	};

	public static List<String> getTitles() {
		return titles;
	}

	@ManyToOne(cascade = ALL)
	@JoinTable(name = "contatto_adder")
	private User adder;

	private String citizenship;

	@OneToMany(cascade = ALL)
	@JoinTable
	// @LazyCollection(LazyCollectionOption.FALSE)
	// Uni-directional
	private List<Email> emails;

	@Transient
	private Email emailToRemove;

	@OneToMany(cascade = ALL)
	@JoinTable
	// @LazyCollection(LazyCollectionOption.FALSE)
	// Uni-directional
	private List<Fax> faxes;

	@NotNull
	private String firstName;

	@Id
	@GeneratedValue
	private Long id;

	@Transient
	private IndirizzoAU indAuToRemove;

	@OneToMany(cascade = ALL)
	@JoinTable
	// Uni-directional
	private List<IndirizzoAU> indirizziAu;

	@OneToMany(cascade = ALL)
	@JoinTable
	// Uni-directional
	private List<IndirizzoIT> indirizziIt;

	@Transient
	private IndirizzoIT indItToRemove;

	private Date insertionDate;

	private String middleName;

	private String note;

	private String passportNumber;

	@Transient
	private Telephone phoneToRemove;

	private String relazione; // relation with the customer in case it's an
								// emergency contact

	private String ruolo; // amico,padre,marketingmanager, etc.
	@NotNull
	private String surname;
	@OneToMany(cascade = ALL)
	@JoinTable
	// @LazyCollection(LazyCollectionOption.FALSE)
	// Uni-directional
	private List<Telephone> telephones;
	private String title;

	public Contatto() {
		super();
		emails = new ArrayList<Email>();
		telephones = new ArrayList<Telephone>();
		faxes = new ArrayList<Fax>();
		indirizziAu = new ArrayList<IndirizzoAU>();
		indirizziIt = new ArrayList<IndirizzoIT>();
	}

	public Contatto(String name, String surname) {
		this();
		this.firstName = name;
		this.surname = surname;
	}

	public boolean add(Email email) {
		// return emails.add(email); // this does not work
		if (this.has(email))
			return false;
		emails.add(email);
		return true;
	}

	public boolean add(Fax fax) {
		if (this.has(fax))
			return false;
		faxes.add(fax);
		return true;
	}

	public boolean add(Telephone tel) {
		if (this.has(tel))
			return false;
		telephones.add(tel);
		return true;
	}

	public void addEmptyEmail() {
		add(new Email());
	}

	public void addEmptyIndAu() {
		getIndirizziAu().add(new IndirizzoAU());
	}

	public void addEmptyIndIt() {
		getIndirizziIt().add(new IndirizzoIT());
	}

	public void addEmptyPhone() {
		add(new Telephone());
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null)
			return false;
		if (!(o instanceof Contatto))
			return false;
		Contatto c = (Contatto) o;
		if (id != null)
			return id.equals(c.getId());
		else {
			if (!(firstName == c.getFirstName()))
				return false;
			if (!(middleName == c.getMiddleName()))
				return false;
			if (!(surname == c.getSurname()))
				return false;
			if (indirizziIt != null)
				return indirizziIt.equals(c.getIndirizziIt());
			if (indirizziIt == null)
				return c.getIndirizziIt() == null;
			if (indirizziAu != null)
				return indirizziAu.equals(c.getIndirizziAu());
			if (indirizziAu == null)
				return c.getIndirizziAu() == null;
			return true;
		}

	}

	public User getAdder() {
		return adder;
	}

	public String getCitizenship() {
		return citizenship;
	}

	public int getEmailNumber() {
		return emails.size();
	}

	public List<Email> getEmails() {
		return emails;
	}

	public Email getEmailToRemove() {
		return emailToRemove;
	}

	public List<Fax> getFaxes() {
		return faxes;
	}

	public String getFirstName() {
		return firstName;
	}

	public Long getId() {
		return id;
	}

	public IndirizzoAU getIndAuToRemove() {
		return indAuToRemove;
	}

	public List<IndirizzoAU> getIndirizziAu() {
		return indirizziAu;
	}

	public List<IndirizzoIT> getIndirizziIt() {
		return indirizziIt;
	}

	public IndirizzoAU getIndirizzoAu() {
		if (indirizziAu.size() < 1)
			return null;
		else
			return indirizziAu.get(0);
	}

	public IndirizzoIT getIndirizzoIt() {
		if (indirizziIt.size() < 2)
			return null;
		else
			return indirizziIt.get(1);
	}

	public IndirizzoIT getIndItToRemove() {
		return indItToRemove;
	}

	public Date getInsertionDate() {
		return insertionDate;
	}

	public String getMiddleName() {
		return middleName;
	}

	public String getNote() {
		return note;
	}

	public String getPassportNumber() {
		return passportNumber;
	}

	public Telephone getPhoneToRemove() {
		return phoneToRemove;
	}

	public String getRelazione() {
		return relazione;
	}

	public String getRuolo() {
		return ruolo;
	}

	public String getSurname() {
		return surname;
	}

	public List<Telephone> getTelephones() {
		return telephones;
	}

	public String getTitle() {
		return title;
	}

	public boolean has(Email au) {
		return emails.contains(au);
	}

	public boolean has(Fax fax) {
		return faxes.contains(fax);
	}

	public boolean has(Telephone tel) {
		return telephones.contains(tel);
	}

	public boolean hasAll(Collection<Email> emails) {
		return this.emails.containsAll(emails);
	}

	public boolean hasEmail(String email) {
		for (Email e : emails)
			if (e.getEmail().equals(email))
				return true;
		return false;
	}

	public boolean hasFax(String number) {
		for (Fax f : faxes)
			if (f.getNumber().equals(number))
				return true;
		return false;
	}

	public boolean hasTelephone(String number) {
		for (Telephone t : telephones)
			if (t.getNumber().equals(number))
				return true;
		return false;
	}

	public boolean remove(Email email) {
		return emails.remove(email);
	}

	public boolean remove(Fax fax) {
		return faxes.remove(fax);
	}

	public boolean remove(Telephone tel) {
		return telephones.remove(tel);
	}

	public void removeEmail() {
		getEmails().remove(emailToRemove);
	}

	public void removeIndAu() {
		getIndirizziAu().remove(indAuToRemove);
	}

	public void removeIndIt() {
		getIndirizziIt().remove(indItToRemove);
	}

	public void removeTelephone() {
		getTelephones().remove(phoneToRemove);
	}

	public void setAdder(User adder) {
		this.adder = adder;
	}

	public void setCitizenship(String citizenship) {
		this.citizenship = citizenship;
	}

	public void setEmails(List<Email> emails) {
		this.emails = emails;
	}

	public void setEmailToRemove(Email emailToRemove) {
		this.emailToRemove = emailToRemove;
	}

	public void setFaxes(List<Fax> faxes) {
		this.faxes = faxes;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public void setIndAuToRemove(IndirizzoAU indAuToRemove) {
		this.indAuToRemove = indAuToRemove;
	}

	public void setIndirizziAu(List<IndirizzoAU> indirizziAu) {
		this.indirizziAu = indirizziAu;
	}

	public void setIndirizziIt(List<IndirizzoIT> indirizziIt) {
		this.indirizziIt = indirizziIt;
	}

	public void setIndirizzoAu(IndirizzoAU ind) {
		if (indirizziAu.isEmpty())
			indirizziAu.add(null);
		indirizziAu.set(0, ind);
	}

	public void setIndirizzoIt(IndirizzoIT ind) {
		if (indirizziIt.isEmpty())
			indirizziIt.add(null);
		indirizziIt.set(0, ind);
	}

	public void setIndItToRemove(IndirizzoIT indItToRemove) {
		this.indItToRemove = indItToRemove;
	}

	public void setInsertionDate(Date insertionDate) {
		this.insertionDate = insertionDate;
	}

	public void setMiddleName(String middleName) {
		this.middleName = middleName;
	}

	public void setNote(String note) {
		this.note = note;
	}

	public void setPassportNumber(String passportNumber) {
		this.passportNumber = passportNumber;
	}

	public void setPhoneToRemove(Telephone phoneToRemove) {
		this.phoneToRemove = phoneToRemove;
	}

	public void setRelazione(String relazione) {
		this.relazione = relazione;
	}

	public void setRuolo(String ruolo) {
		this.ruolo = ruolo;
	}

	public void setSurname(String surname) {
		this.surname = surname;
	}

	public void setTelephones(List<Telephone> telephones) {
		this.telephones = telephones;
	}

	public void setTitle(String title) {
		this.title = title;
	}
	
	@Override
	public String toString() {
		if (getId() != null && getId() != 0L)
			return getId().toString();
		else
			return super.toString();
	}
}
